package com.lezhi.socialgram.service.sys.impl;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.lezhi.socialgram.enums.ResultEnum;
import com.lezhi.socialgram.exception.SocialGramException;
import com.lezhi.socialgram.mapper.sys.SignUpMapper;
import com.lezhi.socialgram.model.lbs.FootPrint;
import com.lezhi.socialgram.model.sys.SignUpUser;
import com.lezhi.socialgram.model.sys.TelNumSignInUser;
import com.lezhi.socialgram.service.im.IMService;
import com.lezhi.socialgram.service.lbs.LbsService;
import com.lezhi.socialgram.service.sys.SignUpService;
import com.lezhi.socialgram.util.*;
import com.lezhi.socialgram.dto.SignUpData;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.DigestUtils;

import javax.servlet.http.HttpServletRequest;
import java.util.Collections;

/**
 * Created by daizhen on 2017/3/26.
 */
@Service
public class SignUpServiceImpl implements SignUpService {

    private static final Logger logger = LoggerFactory.getLogger(SignUpServiceImpl.class);

    @Autowired
    SignUpMapper signUpMapper;

    @Autowired
    StringRedisTemplate stringRedisTemplate;

    @Autowired
    LbsService lbsService;

    @Autowired
    IMService imService;

    @Autowired
    HttpServletRequest request;

    @Override
    @Transactional(propagation = Propagation.REQUIRED, isolation = Isolation.DEFAULT)
    public Result signUp(SignUpUser signUpUser) {
        try {
            //判断手机号是否可以注册
            String indexByTel = XUtil.getTableNameIndexByTel(signUpUser.getTelNum());
            String table = Param.T_USER_TEL_NUM_INDEX_TABLE_PREFIX + indexByTel;
            long countOfTelNum = signUpMapper.countOfTelNum(signUpUser.getTelNum(), table);
            if (countOfTelNum > 0) {
                throw new SocialGramException(ResultEnum.ACCOUNT_IS_EXIST);
            }
            //获取自增id
            Long userSequence = stringRedisTemplate.opsForValue().increment(Param.USER_SEQUENCE, 1);
            signUpUser.setUserId(userSequence);
            //插入索引表,设置表名
            signUpUser.setTable(Param.T_USER_TEL_NUM_INDEX_TABLE_PREFIX + indexByTel);
            signUpMapper.insertUserTelNumIndex(signUpUser);
            //插入用户表,设置表名
            signUpUser.setTable(TableUtils.getTableNameWithId(TelNumSignInUser.class, userSequence, 10));
            //设置客户端ip
            signUpUser.setRemoteIP(XUtil.getRemoteAddr(request));
            //足迹
            signUpUser.setFootPrints(JsonUtils.objectToJson(Collections.singletonList(new FootPrint(signUpUser.getCountry(), signUpUser.getRegion(),
                    signUpUser.getCity(), signUpUser.getCounty()))));
            //加密密码
            String md5DigestAsHex = DigestUtils.md5DigestAsHex(signUpUser.getPassword().getBytes());
            String md5Password = DigestUtils.md5DigestAsHex((userSequence + md5DigestAsHex).getBytes());
            signUpUser.setPassword(md5Password);
            signUpMapper.initUser(signUpUser);
            //保存用户信息到elasticsearch
            lbsService.indexUser(signUpUser);
            stringRedisTemplate.opsForHash().put(userSequence + "user_count", Param.LIKE_COUNT, "0");
            stringRedisTemplate.opsForHash().put(userSequence + "user_count", Param.LIKE_ME_COUNT, "0");
            stringRedisTemplate.opsForHash().put(userSequence + "user_count", Param.LIKE_MY_MOMENT_TOTAL_COUNT, "0");
            stringRedisTemplate.opsForHash().put(userSequence + "user_count", Param.GRANT_TO_ME_COUNT, "0");
            stringRedisTemplate.opsForHash().put(userSequence + "user_count", Param.SEEN_MY_MOMENT_TOTAL_COUNT, "0");
            //新的喜欢我、新的点赞、新的评论、新的礼物、新的@我、新的被收藏、新的被转发
            stringRedisTemplate.opsForHash().put(userSequence + "user_count", Param.NEW_LIKE_ME_COUNT, "0");
            stringRedisTemplate.opsForHash().put(userSequence + "user_count", Param.NEW_LIKE_MY_MOMENT_COUNT, "0");
            stringRedisTemplate.opsForHash().put(userSequence + "user_count", Param.NEW_COMMENT_COUNT, "0");
            stringRedisTemplate.opsForHash().put(userSequence + "user_count", Param.NEW_GIFTS_COUNT, "0");
            stringRedisTemplate.opsForHash().put(userSequence + "user_count", Param.NEW_AT_ME_COUNT, "0");
            stringRedisTemplate.opsForHash().put(userSequence + "user_count", Param.NEW_COLLECT_COUNT, "0");
            stringRedisTemplate.opsForHash().put(userSequence + "user_count", Param.NEW_ZF_COUNT, "0");
            //异步翻译、建立和mqtt的连接
            new Thread(() -> imService.connect(userSequence)).start();
            //同步查出附近的20个人返回
//            List<UserNearly> userNearlyList =
//                    lbsService.queryPersonNearlyByLatLon(signUpUser.getLat(), signUpUser.getLon(), signUpUser.getSex() == 1 ? 2 : 1);
            return ResultUtils.success(new SignUpData(userSequence, null));
        } catch (Exception e) {
            throw e;
        }
    }

    @Override
    public Result checkTelNumSignUp(String telNum) {
        try {
            //判断手机号是否可以注册
            String indexByTel = XUtil.getTableNameIndexByTel(telNum);
            String table = Param.T_USER_TEL_NUM_INDEX_TABLE_PREFIX + indexByTel;
            long countOfTelNum = signUpMapper.countOfTelNum(telNum, table);
            if (countOfTelNum > 0) {
                throw new SocialGramException(ResultEnum.ACCOUNT_IS_EXIST);
            }
            return ResultUtils.success();
        } catch (Exception e) {
            throw e;
        }
    }
}
